package com.jzo2o.foundations.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.common.expcetions.CommonException;
import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.foundations.enums.FoundationStatusEnum;
import com.jzo2o.foundations.mapper.RegionMapper;
import com.jzo2o.foundations.mapper.ServeItemMapper;
import com.jzo2o.foundations.mapper.ServeMapper;
import com.jzo2o.foundations.model.domain.Region;
import com.jzo2o.foundations.model.domain.Serve;
import com.jzo2o.foundations.model.domain.ServeItem;
import com.jzo2o.foundations.model.dto.request.ServePageQueryReqDTO;
import com.jzo2o.foundations.model.dto.request.ServeUpsertReqDTO;
import com.jzo2o.foundations.model.dto.response.ServeResDTO;
import com.jzo2o.foundations.service.IServeService;
import com.jzo2o.mysql.utils.PageHelperUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

@Service
public class ServeServiceImpl extends ServiceImpl<ServeMapper, Serve> implements IServeService {

    @Resource
    private ServeItemMapper serveItemMapper;

    @Resource
    private RegionMapper regionMapper;



    /**
     * 区域服务型分页查询
     *
     * @param dto
     * @return
     */
    @Override
    public PageResult<ServeResDTO> page(ServePageQueryReqDTO dto) {

        return PageHelperUtils.selectPage(dto,
                () -> baseMapper.queryList(dto.getRegionId()));
    }


    /**
     * 区域服务批量新增
     *
     * @param serveUpsertReqDTOList
     */
    @Override
    @Transactional
    public void batchAdd(List<ServeUpsertReqDTO> serveUpsertReqDTOList) {




//        1.遍历集合，校验新增服务是否满足条件(1.没被禁用  2.服务不存在)
        for (ServeUpsertReqDTO serveUpsertReqDTO : serveUpsertReqDTOList) {

//            2. 查询该服务是否被禁用
            ServeItem serveItem = serveItemMapper.selectById(serveUpsertReqDTO.getServeItemId());
            //如果服务项信息不存在或未启用,直接抛异常
            if(ObjectUtil.isNull(serveItem) || serveItem.getActiveStatus()!= FoundationStatusEnum.ENABLE.getStatus()){
                throw new ForbiddenOperationException("该服务未启用无法添加到区域下使用");
            }

//            3. 查询该服务是否已存在
            Integer count = lambdaQuery()
                    .eq(Serve::getRegionId, serveUpsertReqDTO.getRegionId())
                    .eq(Serve::getServeItemId, serveUpsertReqDTO.getServeItemId())
                    .count();
            //如果服务已存在,直接抛异常
            if(count>0){
                throw new ForbiddenOperationException(serveItem.getName()+"服务已存在");
            }

            //3.新增服务
            Serve serve = BeanUtil.toBean(serveUpsertReqDTO, Serve.class);
            Region region = regionMapper.selectById(serveUpsertReqDTO.getRegionId());
            serve.setCityCode(region.getCityCode());
            baseMapper.insert(serve);
        }
    }


    /**
     * 区域服务项修改价格
     *
     * @param id
     * @param price
     */
    @Override
    @Transactional
    public Serve update(Long id, BigDecimal price) {
//        1. 根据Id查询服务
        Serve serve = baseMapper.selectById(id);
        if(ObjectUtil.isNull(serve)){
            throw new ForbiddenOperationException("区域服务不存在");
        }

        boolean update = lambdaUpdate()
                .eq(Serve::getId, id)
                .set(Serve::getPrice, price)
                .update();
        if(!update){
            throw new CommonException("修改服务价格失败");
        }

        return serve;
    }


    /**
     * 区域服务项目上架
     *
     * @param id
     */
    @Override
    public Serve onSale(Long id) {
//        1. 根据Id查询项目
        Serve serve = baseMapper.selectById(id);

//        2. 该区域服务存在才可上架
        if(ObjectUtil.isNull(serve)){
            throw new ForbiddenOperationException("区域服务不存在");
        }

//        3. 草稿和下架的状态才可上架
        Integer saleStatus = serve.getSaleStatus();
        if (!(saleStatus==FoundationStatusEnum.INIT.getStatus() || saleStatus==FoundationStatusEnum.DISABLE.getStatus())) {
            throw new ForbiddenOperationException("草稿或下架状态方可上架");
        }

//        4. 服务项Id存在才可上架
        Long serveItemId = serve.getServeItemId();
        ServeItem serveItem = serveItemMapper.selectById(serveItemId);
        if(ObjectUtil.isNull(serveItemId)){
            throw new ForbiddenOperationException("所属服务项不存在");
        }

//        5. 服务项的启用状态才可上架
        Integer activeStatus = serveItem.getActiveStatus();
        //服务项为启用状态方可上架
        if (!(FoundationStatusEnum.ENABLE.getStatus()==activeStatus)) {
            throw new ForbiddenOperationException("服务项为启用状态才可上架");
        }

//        6. 更新上架状态
        boolean update = lambdaUpdate()
                .eq(Serve::getId, id)
                .set(Serve::getSaleStatus, FoundationStatusEnum.ENABLE.getStatus())
                .update();
        if(!update){
            throw new CommonException("启动服务失败");
        }

        return serve;
    }


    /**
     * 区域服务下架
     *
     * @param id
     */
    @Override
    public Serve offSale(Long id) {
//        1.根据Id查询服务
        Serve serve = baseMapper.selectById(id);

//        2. 服务存在才可下架
        if(ObjectUtil.isNull(serve)){
            throw new ForbiddenOperationException("区域服务不存在");
        }

//        3. 服务上架状态才可下架
        Integer saleStatus = serve.getSaleStatus();
        if (!(saleStatus==FoundationStatusEnum.ENABLE.getStatus())) {
            throw new ForbiddenOperationException("该服务未上架");
        }

//        4. 修改上架状态信息
        boolean update = lambdaUpdate()
               .eq(Serve::getId, id)
               .set(Serve::getSaleStatus, FoundationStatusEnum.DISABLE.getStatus())
               .update();
        if(!update){
            throw new CommonException("下架服务失败");
        }
        return serve;
    }


    /**
     * 区域服务项目删除
     *
     * @param id
     */
    @Override
    public void delete(Long id) {
//        1. 根据Id查询该服务
        Serve serve = baseMapper.selectById(id);

//        2.项目存在才可删除
        if(ObjectUtil.isNull(serve)){
            throw new ForbiddenOperationException("区域服务不存在");
        }

//        3. 服务状态为草稿和下架才可删除
        Integer saleStatus = serve.getSaleStatus();
        if (!(saleStatus==FoundationStatusEnum.INIT.getStatus() || saleStatus==FoundationStatusEnum.DISABLE.getStatus())) {
            throw new ForbiddenOperationException("草稿或下架状态方可删除");
        }


//        4. 删除该区域服务项
        serveItemMapper.deleteById(serve.getId());
    }


    /**
     * 区域服务项目置为热门
     *
     * @param id
     */
    @Override
    public void onHot(Long id) {
//        1. 根据Id查询服务
        Serve serve = baseMapper.selectById(id);

//        2. 服务存在才可置为热门
        if(ObjectUtil.isNull(serve)){
            throw new ForbiddenOperationException("区域服务不存在");
        }

//        3. 服务状态为上架状态才可置为热门
        Integer saleStatus = serve.getSaleStatus();
        if (!(saleStatus==FoundationStatusEnum.ENABLE.getStatus())) {
            throw new ForbiddenOperationException("该服务未上架");
        }

//        4. 服务不是热门才可设置热门
        Integer hotStatus = serve.getIsHot();
        if (!(hotStatus==0)) {
            throw new ForbiddenOperationException("该服务已是热门");
        }

//        5. 设置服务为热门
        boolean update = lambdaUpdate()
               .eq(Serve::getId, id)
               .set(Serve::getIsHot, 1)
               .update();
        if(!update){
            throw new CommonException("置为热门失败");
        }
    }


    /**
     * 区域服务项目取消热门
     *
     * @param id
     */
    @Override
    public void offHot(Long id) {
//        1. 根据Id查询服务
        Serve serve = baseMapper.selectById(id);

//        2. 服务存在才可置为非热门
        if(ObjectUtil.isNull(serve)){
            throw new ForbiddenOperationException("区域服务不存在");
        }

//        3. 服务状态为上架状态才可置为非热门
        Integer saleStatus = serve.getSaleStatus();
        if (!(saleStatus==FoundationStatusEnum.ENABLE.getStatus())) {
            throw new ForbiddenOperationException("该服务未上架");
        }

//        4. 服务是热门才可设置非热门
        Integer hotStatus = serve.getIsHot();
        if (!(hotStatus==1)) {
            throw new ForbiddenOperationException("该服务不是热门");
        }

//        5. 设置服务为非热门
        boolean update = lambdaUpdate()
               .eq(Serve::getId, id)
               .set(Serve::getIsHot, 0)
               .update();
        if(!update){
            throw new CommonException("取消热门失败");
        }

    }

}
